package amqplib

import (
	"errors"
	"time"

	"github.com/brotherbaby/jinzhugo/logger"
	"github.com/google/uuid"
)

const (
	ReplyToQueuePrefix = "rpc_reply_"
	// 定义超时时间
	RPCTimeout = 10 * time.Second
)

func Init(mccm *MQConnectorConfigMap) *RabbitMQFactory {
	var rf RabbitMQFactory
	if rf.rsm == nil {
		rf.rsm = make(map[string]*RabbitMQ)
	}
	for k, mcc := range mccm.mccm {
		var r *RabbitMQ
		err := r.InitRabbitMQ(&mcc, &mccm.cpc)
		if err != nil {
			logger.Error("failed to initialize RabbitMQ for key %s: %w", k, err)
			return nil
		}
		rf.rsm[k] = r
	}
	return &rf
}

func (rf *RabbitMQFactory) SendMQ(mqName string, pm MQPublishMessage) error {
	rm := rf.rsm[mqName]
	if rm == nil {
		logger.Error("SendMQ not found mq ins by %s", mqName)
		return errors.New("SendMQ not found mq ins.")
	}
	rm.Publish(pm, false)
	return nil
}

func (rf *RabbitMQFactory) MQRpc(mqName string, pm MQPublishMessage, timeOut int) (*MQConsumerMessage, error) {
	rm := rf.rsm[mqName]
	if rm == nil {
		logger.Error("MQRpc not found mq ins by %s", mqName)
		return nil, errors.New("MQRpc not found mq ins.")
	}
	// 生成唯一的 replyTo 队列名和CorrelationID
	replyToQueue := ReplyToQueuePrefix + time.Now().String()
	pm.ReplyTo = replyToQueue
	pm.CorrelationID = uuid.New().String()

	pm.Response = make(chan MQConsumerMessage, 1)

	err := rm.Publish(pm, true)
	if err != nil {
		return nil, err
	}

	rpcTimeout := RPCTimeout
	if timeOut > 0 {
		rpcTimeout = time.Duration(timeOut)
	}
	select {
	case response := <-pm.Response:
		return &response, nil
	case <-time.After(rpcTimeout):
		return nil, errors.New("RPC call timed out")
	}
}

func (rf *RabbitMQFactory) ConsumeMQ(mqName string, cm MQConsumerMessage) error {
	rm := rf.rsm[mqName]
	if rm == nil {
		logger.Error("ConsumeMQ not found mq ins by %s", mqName)
		return errors.New("ConsumeMQ not found mq ins.")
	}
	rm.Consume(cm)
	return nil
}
